<!-- 
废渣项目-监管地图首页
地图版本:高德地图js-api:v2.0
主要功能：
1.地图的初始化
2.车辆位置标注
3.车辆位置更新
4.车辆标注的菜单操作
 -->
<template>
  <div></div>
</template>
<script>
//https://developer.amap.com/demo/jsapi-v2/example/mass-markers/labelmarker-mass
import AMap from "AMap";
import AMapUI from "AMapUI";
export default {
  data() {
    return {
      //地图实例
      map: null,
      labelsLayer: null,
      //车牌号查看文本显示标记对象
      plateNoMarker: new AMap.Marker({
        anchor: "bottom-center",
        offset: [0, -40],
      }),
      pathSimplifier: null,
    };
  },

  methods: {
    /**
     * 初始化地图实例
     * @param  domId 布局元素id
     * @param  position 地图中心位置
     * @param  zoom 缩放级别[3-20]
     * @returns  地图对象
     */
    initMap(domId, position, zoom) {
      this.map = new AMap.Map(domId, {
        resizeEnable: true, //是否监控地图容器尺寸变化
        zoom: zoom, //初始化地图层级
        center: position, //初始化地图中心点
        mapStyle: "amap://styles/light", //设置地图的显示样式
      });
      AMap.plugin(["AMap.ToolBar", "AMap.Scale"], () => {
        // 在图面添加工具条控件，工具条控件集成了缩放、平移、定位等功能按钮在内的组合控件
        this.map.addControl(new AMap.ToolBar());
        // 在图面添加比例尺控件，展示地图在当前层级和纬度下的比例尺
        this.map.addControl(new AMap.Scale());
      });
      this.map.on("complete", () => {
        // 创建 AMap.LabelsLayer 图层,标注图层，用于添加 LabelMarker 类型标注
        this.labelsLayer = new AMap.LabelsLayer({
          zooms: [3, 20],
          zIndex: 1000,
          collision: false,
        });
        this.map.add(this.labelsLayer);
      });
    },
    /**
     * 创建车辆位置标注
     */
    createCarMarker(plateNo, position, isBusy) {
      let labelMarker = new AMap.LabelMarker({
        name: plateNo,
        position: position,
        rank: isBusy ? 2 : 1,
        icon: {
          image: isBusy
            ? require("@/assets/icons/car_busy.png")
            : require("@/assets/icons/car_idle.png"),
          size: [40, 40],
          anchor: "bottom-center",
        },
      });
      //事件
      labelMarker.on("mouseover", (e) => {
        var position = e.data.data && e.data.data.position;
        if (position) {
          this.plateNoMarker.setContent(
            '<div class="amap-info-window">' +
              e.target.getName() +
              '<div class="amap-info-sharp"></div>' +
              "</div>"
          );
          this.plateNoMarker.setPosition(position);
          this.map.add(this.plateNoMarker);
        }
      });
      labelMarker.on("mouseout", () => {
        this.map.remove(this.plateNoMarker);
      });
      labelMarker.on("rightclick", (e) => {
        console.log(e);
        let menu = this.createCarContextMenu(e.target.getName());
        menu.open(this.map, e.lnglat);
      });
      return labelMarker;
    },

    updateCarMarkerIcon(marker, isBusy) {
      let rank = marker.getRank();
      if (rank == 2 && isBusy) return;
      marker.setRank(isBusy ? 2 : 1);
      marker.setIcon({
        image: isBusy
          ? require("@/assets/icons/car_busy.png")
          : require("@/assets/icons/car_idle.png"),
        size: [40, 40],
        anchor: "bottom-center",
      });
    },
    updateCarMarkerPosition(marker, position) {
      if (marker && position) {
        marker.setPosition(position);
      }
    },
    moveMapCenterToLocation(position) {
      this.map.panTo(position);
    },
    /**
     *根据地图上添加的覆盖物分布情况，自动缩放地图到合适的视野级别，参数均可缺省。
     *overlayList为覆盖物数组，缺省时为当前地图上添加的所有覆盖物图层，
     *immediately代表是否需要动画过程，avoid代表上下左右的像素避让宽度，maxZoom代表fitView之后的最大级别
     */
    setFitView(overlayList) {
      this.map.setFitView(overlayList, true, [48, 48, 48, 48]);
    },
    /**
     * 自定义车辆标注右键菜单
     * 点击事件在vue中无效的解决办法，参考：https://blog.csdn.net/qq_39503511/article/details/110918668
     * <p>
     * 在高德地图中，使用infoWindow来创建信息窗体，如果是原生的html+css，
     * 可以很方便的实现信息窗体的绑定事件，直接在需要交互的部分直接使用onclick进行绑定即可，
     * 但在vue中这么使用并不行，并不能把绑定的方法直接写在methods中，这是因为vue中methods的方法是只对template模板中的内容才起作用，
     * 我们传递到infoWindow中的content的值是字符串，然后高德地图在进行渲染，所以我的解决方案是直接把方法给绑定到window对象中。
     * </p>
     */
    createCarContextMenu(plateNo) {
      var content = [];
      content.push("<div class='info context_menu'>");
      content.push(`<p onclick="zoomMenu('${plateNo}')">缩小</p>`);
      content.push("<p onclick='zoomMenu(1)'>放大</p>");
      content.push("<p onclick='menu.addMarkerMenu()'>添加标记</p>");
      content.push("</div>");
      //通过content自定义右键菜单内容
      var contextMenu = new AMap.ContextMenu({
        isCustom: true,
        content: content.join(""),
      });

      window.zoomMenu = (num) => {
        console.log("======>", num);
        contextMenu.close();
      };
      return contextMenu;
    },
    /**
     * 显示以某个点为中心，一定半径内的覆盖范围
     * @param position 位置中心
     * @param radius 半径，单位米
     */
    showConverCircle(position, radius) {
      var circle = new AMap.Circle({
        center: position,
        radius: radius, //半径
        borderWeight: 3,
        strokeColor: "#224b8f",
        strokeOpacity: 1,
        strokeWeight: 6,
        fillOpacity: 0.4,
        strokeStyle: "dashed",
        strokeDasharray: [10, 10],
        // 线样式还支持 'dashed'
        fillColor: "#1791fc",
        zIndex: 50,
      });
      this.map.add(circle);
      // 缩放地图到合适的视野级别
      this.map.setFitView([circle]);
    },
    /**
     * 获取轨迹绘制线
     * @param path 初始位置数组
     */
    getTraceDrawLine() {
      // 创建折线实例
      var polyline = new AMap.Polyline({
        borderWeight: 2, // 线条宽度，默认为 1
        strokeColor: "red", // 线条颜色
        lineJoin: "round", // 折线拐点连接处样式
        showDir: true,
        strokeWeight: 8, // 线宽
      });
      // 将折线添加至地图实例
      this.map.add(polyline);
      return polyline;
    },
    /**
     * 初始化轨迹绘制
     */
    initPathSimplifier() {
      //加载PathSimplifier，loadUI的路径参数为模块名中 'ui/' 之后的部分
      AMapUI.load(["ui/misc/PathSimplifier"], (PathSimplifier) => {
        if (!PathSimplifier.supportCanvas) {
          alert("当前环境不支持 Canvas！");
          return;
        }
        //创建组件实例
        var pathSimplifierIns = new PathSimplifier({
          zIndex: 100,
          map: this.map, //所属的地图实例
          getPath: function (pathData) {
            //返回轨迹数据中的节点坐标信息，[AMap.LngLat, AMap.LngLat...] 或者 [[lng|number,lat|number],...]
            return pathData.path;
          },
          getHoverTitle: function (pathData, pathIndex, pointIndex) {
            //返回鼠标悬停时显示的信息
            if (pointIndex >= 0) {
              //鼠标悬停在某个轨迹节点上
              return (
                pathData.name +
                "，点:" +
                pointIndex +
                "/" +
                pathData.path.length
              );
            }
            //鼠标悬停在节点之间的连线上
            return pathData.name + "，点数量" + pathData.path.length;
          },
          renderOptions: {
            //轨迹线的样式
            pathLineStyle: {
              strokeStyle: "red",
              lineWidth: 6,
              dirArrowStyle: true,
            },
          },
        });
        this.pathSimplifier = pathSimplifierIns;
      });
    },
  },
};
</script>

<style lang="css">
.amap-info-window {
  width: 80px;
  background: #fff;
  border-radius: 3px;
  padding: 4px;
  box-shadow: 0 2px 6px 0 rgba(114, 124, 245, 0.5);
  position: relative;
  font-size: 0.9rem;
}
.amap-info-sharp {
  position: absolute;
  top: 21px;
  bottom: 0;
  left: 50%;
  margin-left: -8px;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-top: 8px solid #fff;
}

.context_menu {
  position: relative;
  min-width: 10rem;
  padding: 4px;
  margin: 0;
  background: white;
  border-radius: 3px;
}

.context_menu p {
  cursor: pointer;
  padding: 8px;
  margin-top: 1px;
  margin-bottom: 0%;
  font-size: 1rem;
}

.context_menu p:hover {
  background: #ccc;
}
</style>